package com.car.rental.vehicle.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.car.rental.vehicle.dto.VehicleQueryDTO;
import com.car.rental.vehicle.dto.VehicleSearchDTO;
import com.car.rental.vehicle.entity.Vehicle;
import com.car.rental.vehicle.enums.VehicleStatus;
import com.car.rental.vehicle.mapper.VehicleMapper;
import com.car.rental.vehicle.service.VehicleMessageService;
import com.car.rental.vehicle.service.VehicleService;
import com.car.rental.vehicle.dto.VehicleAddDTO;
import com.car.rental.vehicle.dto.VehicleUpdateDTO;
import com.car.rental.vehicle.vo.VehicleListVO;
import com.car.rental.vehicle.vo.VehicleDetailVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.UUID;
import java.io.File;
import com.car.rental.vehicle.model.request.VehicleAddRequest;
import com.car.rental.common.core.response.ResponseResult;
import com.car.rental.vehicle.entity.MerchantVehicle;
import com.car.rental.vehicle.mapper.MerchantVehicleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.car.rental.common.exception.BusinessException;
import com.car.rental.vehicle.entity.VehicleImage;
import com.car.rental.vehicle.mapper.VehicleImageMapper;
import javax.annotation.PostConstruct;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

@Service
@RequiredArgsConstructor
public class VehicleServiceImpl extends ServiceImpl<VehicleMapper, Vehicle> implements VehicleService {
    
    private final VehicleMessageService messageService;
    
    @Value("${upload.base-path}")
    private String basePath;
    
    @Value("${upload.path}")
    private String uploadPath;  // 文件上传路径
    
    @Value("${gateway.url}")  // 添加网关地址配置
    private String gatewayUrl;
    
    @Autowired
    private MerchantVehicleMapper merchantVehicleMapper;
    
    @Autowired
    private VehicleImageMapper vehicleImageMapper;
    
    private static final Logger log = LoggerFactory.getLogger(VehicleServiceImpl.class);
    
    @PostConstruct
    public void init() {
        // 创建上传目录
        File uploadDir = new File(basePath + uploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        log.info("初始化上传目录: {}", uploadDir.getAbsolutePath());
    }
    
    /**
     * 更新车辆状态
     * @param id 车辆ID
     * @param status 目标状态（MAINTENANCE-维修中，AVAILABLE-可租用，RENTED-已租出）
     * @return 更新是否成功
     */
    @Override
    public boolean updateStatus(Long id, String status) {
        // 将字符串状态转换为整数
        Integer statusCode;
        switch (status.toUpperCase()) {
            case "MAINTENANCE":
                statusCode = 0;
                break;
            case "AVAILABLE":
                statusCode = 1;
                break;
            case "RENTED":
                statusCode = 2;
                break;
            default:
                throw new BusinessException("无效的状态值");
        }
        
        // 获取车辆并更新状态
        Vehicle vehicle = getById(id);
        if (vehicle == null) {
            throw new BusinessException("车辆不存在");
        }
        
        vehicle.setStatus(statusCode);
        return updateById(vehicle);
    }
    
    /**
     * 将状态码转换为状态字符串
     */
    private String convertStatusToString(Integer status) {
        switch(status) {
            case 0: return "MAINTENANCE";  // 维修中
            case 1: return "AVAILABLE";    // 可租用
            case 2: return "RENTED";       // 已租出
            default: return "UNKNOWN";     // 未知状态
        }
    }
    
    /**
     * 检查车辆是否可租用
     * @param id 车辆ID
     * @return 是否可租用
     */
    @Override
    public boolean isAvailable(Long id) {
        Vehicle vehicle = getById(id);
        return vehicle != null && vehicle.getStatus() == 1;  // 1表示可租用状态
    }
    
    /**
     * 高级查询车辆列表
     * @param queryDTO 查询条件
     * @param current 当前页
     * @param size 每页大小
     * @return 分页结果
     */
    @Override
    public Page<Vehicle> queryVehicles(VehicleQueryDTO queryDTO, Integer current, Integer size) {
        LambdaQueryWrapper<Vehicle> wrapper = new LambdaQueryWrapper<>();
        
        // 构建查询条件
        if (queryDTO.getType() != null) {
            wrapper.eq(Vehicle::getType, queryDTO.getType());        // 按车型查询
        }
        if (queryDTO.getBrand() != null) {
            wrapper.eq(Vehicle::getBrand, queryDTO.getBrand());      // 按品牌查询
        }
        if (queryDTO.getSeats() != null) {
            wrapper.eq(Vehicle::getSeats, queryDTO.getSeats());      // 按座位数查询
        }
        if (queryDTO.getMaxPrice() != null) {
            wrapper.le(Vehicle::getDailyPrice, queryDTO.getMaxPrice()); // 最高价格
        }
        if (queryDTO.getMinPrice() != null) {
            wrapper.ge(Vehicle::getDailyPrice, queryDTO.getMinPrice()); // 最低价格
        }
        if (queryDTO.getStatus() != null) {
            wrapper.eq(Vehicle::getStatus, queryDTO.getStatus());    // 按状态查询
        }
        
        return page(new Page<>(current, size), wrapper);
    }
    
    /**
     * 批量更新车辆状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateStatus(Long[] ids, String status) {
        try {
            VehicleStatus.valueOf(status);
        } catch (IllegalArgumentException e) {
            return false;
        }
        
        return Arrays.stream(ids)
                .allMatch(id -> updateStatus(id, status));
    }
    
    /**
     * 搜索车辆
     * 支持关键字搜索、条件筛选
     */
    @Override
    public Page<Vehicle> search(VehicleSearchDTO searchDTO, Integer current, Integer size) {
        LambdaQueryWrapper<Vehicle> wrapper = new LambdaQueryWrapper<>();
        
        // 关键字搜索（品牌、型号、车牌号）
        if (searchDTO.getKeyword() != null) {
            wrapper.and(w -> w
                    .like(Vehicle::getBrand, searchDTO.getKeyword())
                    .or()
                    .like(Vehicle::getModel, searchDTO.getKeyword())
                    .or()
                    .like(Vehicle::getVehicleNo, searchDTO.getKeyword()));
        }
        
        // 条件筛选
        if (searchDTO.getType() != null) {
            wrapper.eq(Vehicle::getType, searchDTO.getType());         // 车型
        }
        if (searchDTO.getMinSeats() != null) {
            wrapper.ge(Vehicle::getSeats, searchDTO.getMinSeats());    // 最小座位数
        }
        if (searchDTO.getMaxSeats() != null) {
            wrapper.le(Vehicle::getSeats, searchDTO.getMaxSeats());    // 最大座位数
        }
        if (searchDTO.getMinPrice() != null) {
            wrapper.ge(Vehicle::getDailyPrice, searchDTO.getMinPrice()); // 最低价格
        }
        if (searchDTO.getMaxPrice() != null) {
            wrapper.le(Vehicle::getDailyPrice, searchDTO.getMaxPrice()); // 最高价格
        }
        if (searchDTO.getStatus() != null) {
            wrapper.eq(Vehicle::getStatus, searchDTO.getStatus());      // 车辆状态
        }
        
        return page(new Page<>(current, size), wrapper);
    }
    
    /**
     * 统计各状态车辆数量
     */
    @Override
    public Map<String, Long> countByStatus() {
        List<Vehicle> vehicles = list();
        return vehicles.stream()
                .collect(Collectors.groupingBy(
                        vehicle -> convertStatusToString(vehicle.getStatus()),
                        Collectors.counting()
                ));
    }
    
    /**
     * 获取车辆列表（简要信息）
     */
    @Override
    public Page<VehicleListVO> getVehicleList(Integer current, Integer size, String type, String brand) {
        // 1. 查询车辆基本信息
        Page<Vehicle> page = new Page<>(current, size);
        
        QueryWrapper<Vehicle> wrapper = new QueryWrapper<>();
        
        // 添加查询条件
        if (type != null && !type.isEmpty()) {
            wrapper.eq("type", type);
        }
        if (brand != null && !brand.isEmpty()) {
            wrapper.eq("brand", brand);
        }
        
        // 添加状态条件，使用 tinyint 类型
        wrapper.eq("status", (byte)1);  // 修改这里，使用 byte 类型
        
        // 添加排序
        wrapper.orderByDesc("create_time");
        
        log.info("执行SQL查询，条件: {}", wrapper.getSqlSegment());
        
        Page<Vehicle> vehiclePage = page(page, wrapper);
        log.info("查询结果: total={}, records={}", vehiclePage.getTotal(), vehiclePage.getRecords());
        
        // 2. 转换为VO对象
        Page<VehicleListVO> voPage = new Page<>(current, size, vehiclePage.getTotal());
        if (vehiclePage.getRecords().isEmpty()) {
            return voPage;
        }
        
        // 转换数据
        List<VehicleListVO> voList = vehiclePage.getRecords().stream()
                .map(this::convertToListVO)
                .collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }

    private VehicleListVO convertToListVO(Vehicle vehicle) {
        VehicleListVO vo = new VehicleListVO();
        vo.setId(vehicle.getId());
        vo.setBrand(vehicle.getBrand());
        vo.setModel(vehicle.getModel());
        vo.setVehicleNo(vehicle.getVehicleNo());
        vo.setImageUrl(vehicle.getImageUrl());
        vo.setDailyPrice(vehicle.getDailyPrice());
        vo.setStatus(vehicle.getStatus());
        vo.setAddress(vehicle.getAddress());
        return vo;
    }

    /**
     * 获取车辆详情
     */
    @Override
    public VehicleDetailVO getVehicleDetail(Long id) {
        // 1. 获取车辆基本信息
        Vehicle vehicle = getById(id);
        if (vehicle == null) {
            return null;
        }
        
        // 2. 转换为VO对象
        VehicleDetailVO vo = new VehicleDetailVO();
        BeanUtils.copyProperties(vehicle, vo);
        
        return vo;
    }

    /**
     * 上传车辆图片
     * @param file 图片文件
     * @return 图片访问URL
     */
    @Override
    public String uploadImage(MultipartFile file) {
        try {
            // 构建文件存储路径
            String fileName = UUID.randomUUID().toString() + getFileExtension(file.getOriginalFilename());
            String relativePath = uploadPath + fileName;
            String absolutePath = basePath + relativePath;
            
            // 输出实际存储路径
            log.info("图片存储路径: {}", absolutePath);
            
            // 保存文件
            File destFile = new File(absolutePath);
            if (!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }
            
            // 使用 Files.copy 替代 transferTo
            Files.copy(file.getInputStream(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            
            // 只返回相对路径，不要包含网关地址
            return "/vehicle/uploads/vehicle/" + fileName;
            
        } catch (Exception e) {
            log.error("Failed to upload file: {}", e.getMessage(), e);
            throw new BusinessException("上传文件失败: " + e.getMessage());
        }
    }

    private String getFileExtension(String filename) {
        return filename.substring(filename.lastIndexOf("."));
    }

    /**
     * 添加车辆
     */
    @Override
    public boolean save(VehicleAddDTO addDTO) {
        Vehicle vehicle = new Vehicle();
        BeanUtils.copyProperties(addDTO, vehicle);
        vehicle.setStatus(1);  // 设置初始状态为可租用
        return save(vehicle);
    }

    /**
     * 更新车辆信息
     */
    @Override
    public boolean update(VehicleUpdateDTO updateDTO) {
        Vehicle vehicle = new Vehicle();
        BeanUtils.copyProperties(updateDTO, vehicle);
        return updateById(vehicle);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> addVehicle(VehicleAddRequest request, MultipartFile image) {
        // 1. 上传图片
        String imageUrl = uploadImage(image);
        
        // 2. 保存车辆信息
        Vehicle vehicle = new Vehicle();
        BeanUtils.copyProperties(request, vehicle);
        vehicle.setImageUrl(imageUrl);
        vehicle.setStatus(1);  // 1 表示可用状态
        
        baseMapper.insert(vehicle);

        // 3. 保存商家车辆关联信息
        MerchantVehicle merchantVehicle = new MerchantVehicle();
        merchantVehicle.setMerchantId(request.getMerchantId());
        merchantVehicle.setVehicleId(vehicle.getId());
        merchantVehicleMapper.insert(merchantVehicle);

        // 4. 保存车辆图片信息
        VehicleImage vehicleImage = new VehicleImage();
        vehicleImage.setVehicleId(vehicle.getId());
        vehicleImage.setUrl(imageUrl);
        vehicleImageMapper.insert(vehicleImage);

        return ResponseResult.success();
    }

    @Override
    public ResponseResult<Void> updateStatus(Long vehicleId, Integer status) {
        // 验证状态值
        VehicleStatus.fromCode(status);
        
        Vehicle vehicle = getById(vehicleId);
        if (vehicle == null) {
            throw new BusinessException("车辆不存在");
        }
        
        vehicle.setStatus(status);
        updateById(vehicle);
        
        return ResponseResult.success();
    }

    @Override
    public Page<VehicleListVO> getMerchantVehicles(Long merchantId, Integer current, Integer size) {
        Page<Vehicle> page = new Page<>(current, size);
        
        // 通过 merchant_vehicle 关联表查询
        LambdaQueryWrapper<Vehicle> wrapper = new LambdaQueryWrapper<>();
        wrapper.inSql(Vehicle::getId, 
            "SELECT vehicle_id FROM merchant_vehicle WHERE merchant_id = " + merchantId);
        
        page = baseMapper.selectPage(page, wrapper);
        
        // 转换为 VO
        Page<VehicleListVO> voPage = new Page<>(current, size, page.getTotal());
        voPage.setRecords(page.getRecords().stream()
                .map(vehicle -> {
                    VehicleListVO vo = new VehicleListVO();
                    BeanUtils.copyProperties(vehicle, vo);
                    return vo;
                })
                .collect(Collectors.toList()));
        
        return voPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> markAsAvailable(Long vehicleId, Long merchantId) {
        // 1. 验证车辆是否属于该商家
        Long count = merchantVehicleMapper.selectCount(new LambdaQueryWrapper<MerchantVehicle>()
            .eq(MerchantVehicle::getMerchantId, merchantId)
            .eq(MerchantVehicle::getVehicleId, vehicleId));
        
        if (count == 0) {
            throw new BusinessException("无权操作此车辆");
        }

        // 2. 获取车辆信息
        Vehicle vehicle = getById(vehicleId);
        if (vehicle == null) {
            throw new BusinessException("车辆不存在");
        }

        // 3. 检查当前状态是否为维修中
        if (!vehicle.getStatus().equals(VehicleStatus.MAINTENANCE.getCode())) {
            throw new BusinessException("只有维修中的车辆才能标记为可用");
        }

        // 4. 更新状态为可用
        vehicle.setStatus(VehicleStatus.AVAILABLE.getCode());
        updateById(vehicle);

        return ResponseResult.success();
    }
} 